<?php

declare(strict_types=1);

namespace App\Library\Task\library\queue\drivers\mns;

use AliyunMNS\Client;
use AliyunMNS\Exception\MnsException;
use AliyunMNS\Requests\SendMessageRequest;
use function App\Helpers\callback;
use App\Library\Log\Log;

class QueueDBMns
{
    //定义对象
    private $_mns;
    private $accessId;
    private $accessKey;
    private $endPoint;
    private $_driverName;
    private $_receiptHandle;

    /**
     * 初始化
     */
    public function __construct()
    {
        $this->accessId = config('goods.task_drivers_default.mns.access_id');
        $this->accessKey = config('goods.task_drivers_default.mns.access_key');
        $this->endPoint = config('goods.task_drivers_default.mns.end_point');

        $this->_mns = new Client($this->endPoint, $this->accessId, $this->accessKey);
    }

    /**
     * @param $messageBody
     * @param string $driver
     * @return \App\Helpers\multitype
     * 入列
     */
    public function push($messageBody, $driver = 'default')
    {
        //队列内容为空，则直接返回
        if (empty($messageBody)) {
            return callback(false, '参数为空');
        }
        $queue = $this->_mns->getQueueRef($driver);
        $request = new SendMessageRequest($messageBody);
        try {
            $res = $queue->sendMessage($request);
            if ($res->isSucceed()) {
                return callback(true);
            }
            return callback(false, '发送失败');
        } catch (MnsException $exception) {
            Log::error($exception, 'mns队列压入失败');
            return callback(false, '发送失败，'. $exception->getMessage());
        }
    }

    /**
     * 取得所有的list key(表)
     */
    public function scan($driver = 'default')
    {
        $driver = str_replace('_', '-', $driver);
        $this->_driverName = $driver;
        return $driver;
    }

    /**
     * @param $driver
     * @param int $time
     * @return bool|null
     * 出列
     */
    public function pop($driver, $time = 30)
    {
        if (empty($driver)) {
            return null;
        }
        $driver = str_replace('_', '-', $driver);

        $time > 30 && $time = 30;
        $time < 0 && $time = 0;
        $driver = $this->handleDriverName($driver);
        try {
            $queue = $this->_mns->getQueueRef($driver);
            $res = $queue->receiveMessage($time);
            // 2. 获取ReceiptHandle，这是一个有时效性的Handle，可以用来设置Message的各种属性和删除Message。具体的解释请参考：help.aliyun.com/document_detail/27477.html 页面里的ReceiptHandle
            $this->_receiptHandle = $res->getReceiptHandle();
            if ($res->isSucceed()) {
                return $res->getMessageBody();
            } else {
                return false;
            }
        } catch (\Exception $exception) {
//            Log::error($exception, 'mns队列读取失败');
            return false;
        }
    }

    /**
     * 清空,暂时无用
     */
    public function clear($driver = 'default')
    {
        return true;
    }

    /**
     * 删除队列任务
     * @param $driver
     * @return bool
     */
    public function delete($driver) {
        $driver = $this->handleDriverName($driver);
        try {
            $queue = $this->_mns->getQueueRef($driver);
            // 5. 直接调用deleteMessage即可。
            $queue->deleteMessage($this->_receiptHandle);
            return ['state'=>true, 'msg'=>''];
        } catch (MnsException $e) {
            return ['state'=>false, 'msg'=>$e];
        }
    }

    private function handleDriverName($driverName)
    {
        return str_replace('_', '-', $driverName);
    }

}